<?php
/**
 * @version sofortueberweisung.de 5.1.0 - $Date: 2012-04-13 13:32:22 +0200 (Fri, 13 Apr 2012) $
 * @author $Author: boehm $
 * @link http://www.payment-network.com/
 *
 * Copyright (c) 2011 Payment Network AG
 *
 * $Id: sofort.php 3792 2012-04-13 11:32:22Z boehm $
 */

require_once(DIR_FS_CATALOG.'callback/sofort/helperFunctions.php');

/**
 * helper function to mask given array items
 * @param mixed $item
 */
function maskSpecialChars(&$item){
	helperFunctions::htmlMaskArray($item);
}

/**
 * Superclass of xt-commerce modules
 */
class sofort {

	/**
	 * check if payment method is allowed in the payment zone
	 * if not: module will be disabled
	 */
	function update_status() {
		global $order;

		$constantValue = constant ('MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_ZONE');
		if (($this->enabled == true) && ((int) $constantValue > 0)) {
			$check_flag = false;
			$check_query = xtc_db_query("SELECT zone_id FROM " . HelperFunctions::escapeSql(TABLE_ZONES_TO_GEO_ZONES) . " WHERE geo_zone_id = '" . HelperFunctions::escapeSql($constantValue) . "' and zone_country_id = '" . HelperFunctions::escapeSql($order->billing['country']['id']) . "' ORDER BY zone_id");
			while ($check = xtc_db_fetch_array($check_query)) {
				if ($check['zone_id'] < 1) {
					$check_flag = true;
					break;
				} elseif ($check['zone_id'] == $order->billing['zone_id']) {
					$check_flag = true;
					break;
				}
			}
			if ($check_flag == false) {
				$this->enabled = false;
			}
		}
	}


	function javascript_validation () {
		return false;
	}


	/**
	 * extended in all modules "by sofort"
	 */
	function pre_confirmation_check ($vars = '') {
		// Fix for XTC Bug
		// We need a cartID
		if (empty($_SESSION['cart']->cartID)) {
			$_SESSION['cart']->cartID = $_SESSION['cart']->generate_cart_id();
		}
	}


	function confirmation () {

		$this->_checkCancelOrder();

		return false;
	}


	function process_button() {
		return false;
	}


	/**
	 * called directly before the PNAG-API-Call is done
	 * The corresponding order is being processed here, bought articles being credited
	 * SofortLib calls Payment Network API
	 */
	function payment_action () {
		global $order, $xtPrice, $insert_id, $shopEncoding;

		$customer_id = $_SESSION['customer_id'];
		$order_id = $insert_id;
		$_SESSION['cart_pn_sofortueberweisung_ID'] = $_SESSION['cart']->cartID . '-' . $insert_id;

		// Fix for XTC Bug
		// $order->info['total'] is in 'before_process' String without Tax, after email it is TEXT with currency
		// so it has to be set here
		if ($_SESSION['customers_status']['customers_status_show_price_tax'] == 0 && $_SESSION['customers_status']['customers_status_add_tax_ot'] == 1) {
			$total = $order->info['total'] + $order->info['tax'];
		} else {
			$total = $order->info['total'];
		}

		$amount = round($total, $xtPrice->get_decimal_places($_SESSION['currency']));
		$amount = number_format($amount, 2, '.', '');

		$parameter = array();
		$currency = $_SESSION['currency'];

		$reason_1 = str_replace('{{order_id}}', $order_id, MODULE_PAYMENT_SOFORT_MULTIPAY_REASON_1);
		$reason_1 = str_replace('{{customer_id}}', $customer_id, $reason_1);
		$reason_1 = substr($reason_1, 0, 27);

		if ($this->paymentMethod != 'SV') {  //SV has only one reason
			$reason_2 = str_replace('{{order_id}}', $order_id, MODULE_PAYMENT_SOFORT_MULTIPAY_TEXT_REASON_2);
			$reason_2 = str_replace('{{customer_id}}', $customer_id, $reason_2);
			$reason_2 = str_replace('{{order_date}}', strftime(DATE_FORMAT_SHORT), $reason_2);
			$reason_2 = str_replace('{{customer_name}}', $order->customer['firstname'] . ' ' . $order->customer['lastname'], $reason_2);
			$reason_2 = str_replace('{{customer_company}}', $order->customer['company'], $reason_2);
			$reason_2 = str_replace('{{customer_email}}', $order->customer['email_address'], $reason_2);
			$reason_2 = substr($reason_2, 0, 27);
		} else {
			$reason_2 = ''; //only SV
		}

		$user_variable_0 = $order_id;
		$user_variable_1 = $customer_id;

		$session = session_name() . '=' . session_id();

		if (ENABLE_SSL == true)
			$server = HTTPS_SERVER;
		else
			$server = HTTP_SERVER;

		// success return url:
		$success_url = $server . DIR_WS_CATALOG . FILENAME_CHECKOUT_PROCESS . '?' . $session;
		// cancel return url:
		$cancel_url = $server . DIR_WS_CATALOG . FILENAME_CHECKOUT_PAYMENT . '?payment_error='.$this->code.'&' . $session;
		// notification url:
		$notification_url = $server . DIR_WS_CATALOG . 'callback/sofort/callback.php'; //deprecated
		$user_variable_2 = $_SESSION['cart']->cartID;

		$this->sofort->setAmount($amount, $currency);
		$this->sofort->setReason(helperFunctions::convertEncoding($reason_1,3), helperFunctions::convertEncoding($reason_2,3));
		$this->sofort->setSuccessUrl(helperFunctions::convertEncoding($success_url,3));
		$this->sofort->setAbortUrl(helperFunctions::convertEncoding($cancel_url,3));
		$this->sofort->setTimeoutUrl(helperFunctions::convertEncoding($cancel_url,3));
		$this->sofort->setNotificationUrl(helperFunctions::convertEncoding($notification_url,3));
		$this->sofort->addUserVariable(helperFunctions::convertEncoding($user_variable_0,3));
		$this->sofort->addUserVariable(helperFunctions::convertEncoding($user_variable_1,3));
		$this->sofort->addUserVariable(helperFunctions::convertEncoding($user_variable_2,3));
		$this->sofort->setEmailCustomer(helperFunctions::convertEncoding($order->customer['email_address'],3));
		$this->sofort->setPhoneNumberCustomer($order->customer['telephone']);

		switch($this->paymentMethod) {
			case 'SU' :
				$this->sofort->setSofortueberweisung($amount);
				// see if customer protection is enabled, set it as parameter to sofortlib
				$this->sofort->setSofortueberweisungCustomerprotection(MODULE_PAYMENT_SOFORT_SU_KS_STATUS == 'True');
				break;
			case 'SL' :
				$this->sofort->setSofortlastschrift();
				$this->sofort->setSenderAccount('', '', helperFunctions::convertEncoding($order->customer['firstname'],3) . ' ' . helperFunctions::convertEncoding($order->customer['lastname'],3));
				break;
			case 'LS' :
				$this->sofort->setLastschrift();
				$this->sofort->setSenderAccount(helperFunctions::convertEncoding($_SESSION['ls_bank_code'],3), helperFunctions::convertEncoding($_SESSION['ls_account_number'],3),  helperFunctions::convertEncoding($_SESSION['ls_sender_holder'],3));

				$billingSalutation = $this->_getGenderFromAddressBook($order->billing['firstname'], $order->billing['lastname'], $order->billing['company'], $order->billing['street_address'],
					$order->billing['postcode'], $order->billing['city'], $order->billing['country_id'], $order->billing['zone_id']);

				//split the street and the number
				if(!preg_match('#(.+)[ .](.+)#i', trim($order->billing['street_address']), $streetparts)) {
					$streetparts = array();
					$streetparts[1] = trim($order->billing['street_address']);
					$streetparts[2] = '';
				}
				//if there is an entry in "suburb" (german: "Adresszusatz"), we put it in front of the streetname
				if ($order->billing['suburb']) {
					$streetparts[1] = $order->billing['suburb'] . ' - ' . $streetparts[1];
				}

				$this->sofort->setLastschriftAddress(helperFunctions::convertEncoding($order->billing['firstname'],3), helperFunctions::convertEncoding($order->billing['lastname'],3), helperFunctions::convertEncoding($streetparts[1],3), helperFunctions::convertEncoding($streetparts[2],3),  $order->billing['postcode'], helperFunctions::convertEncoding($order->billing['city'],3), helperFunctions::convertEncoding($billingSalutation,3), helperFunctions::convertEncoding($order->billing['country']['iso_code_2'],3));
				break;
			case 'SV' :
				$this->sofort->setSofortvorkasse();
				$this->sofort->setSofortvorkasseCustomerprotection(MODULE_PAYMENT_SOFORT_SV_KS_STATUS == 'True');
				break;
		}

		$this->sofort->sendRequest();

		if($this->sofort->isError()) {
			$this->_handleErrors($this->sofort->getErrors(), $cancel_url);
		} else {
			$url = $this->sofort->getPaymentUrl();
			$tid = $this->sofort->getTransactionId();

			$time = strftime(' %Y-%m-%d %H:%M:%S');
			$tmpStatusId = constant ('MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_TMP_STATUS_ID');
			$tmpStatusId = $this->checkStatusId($tmpStatusId);
			$tmpComment = constant ('MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_TMP_COMMENT');
			$customerNotified = HelperFunctions::getIniValue('sofortCustomerNotified');
			
			$sql_data_array = array('orders_id' => (int) $order_id, 'orders_status_id' => $tmpStatusId , 'date_added' => 'sqlcommand:now()' , 'customer_notified' => $customerNotified , 'comments' => $tmpComment.$time);
			xtc_db_query(HelperFunctions::getEscapedInsertInto(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array));
			xtc_db_query('UPDATE '.HelperFunctions::escapeSql(TABLE_ORDERS).' SET orders_ident_key=\''.HelperFunctions::escapeSql($tid).'\' WHERE orders_id=\''.HelperFunctions::escapeSql($order_id).'\'');
			
			$_SESSION['sofort_payment_url'] = $url;
			$_SESSION['sofort_payment_method'] = $this->code;
			xtc_redirect($server . DIR_WS_CATALOG . 'callback/sofort/processSofortPayment.php');
		}
	}


	function before_process() {
		return false;
	}


	/**
	 * delete sofort-vars in the session and set customer notified if user got an order-email
	 */
	function after_process(){
		global $insert_id;
		//if we reached this point the mail is already sent so set customer_notified flag
		if(SEND_EMAILS == 'true' && is_int($insert_id)) {
			//activate following line if needed
			//xtc_db_query('UPDATE '.HelperFunctions::escapeSql(TABLE_ORDERS_STATUS_HISTORY).' SET customer_notified=\'1\' WHERE orders_id=\''.HelperFunctions::escapeSql($insert_id).'\' ORDER BY orders_status_history_id DESC LIMIT 1');
		}

		/* Clear our session data
		 * All other session data will be handled in checkout_process.php
		 */
		if (isset($_SESSION['cart_pn_sofortueberweisung_ID']))
			unset($_SESSION['cart_pn_sofortueberweisung_ID']);
		if (isset($_SESSION['sofort_conditions_sr']))
			unset($_SESSION['sofort_conditions_sr']);
		if (isset($_SESSION['sofort_conditions_sv']))
			unset($_SESSION['sofort_conditions_sv']);
		if (isset($_SESSION['sofort_conditions_ls']))
			unset($_SESSION['sofort_conditions_ls']);
		if (isset($_SESSION['ls_sender_holder']))
			unset($_SESSION['ls_sender_holder']);
		if (isset($_SESSION['ls_account_number']))
			unset($_SESSION['ls_account_number']);
		if (isset($_SESSION['ls_bank_code']))
			unset($_SESSION['ls_bank_code']);
	}


	function output_error() {
		return false;
	}


	/**
	 * redirect to payment-page and include the error_code
	 * @param array $errors within all found errors
	 * @return makes ALWAYS redirect to $cancel_url!
	 */
	function _handleErrors($errors, $cancel_url){
		$errorCodes = array();
		foreach ($errors as $oneError) {
			$errorCodes[] = $oneError['code'];
		}
		if($errorCodes){
			xtc_redirect($cancel_url . '&error_codes=' . implode(',', $errorCodes) );
		}else{
			//error_code was not found - should never appear...
			xtc_redirect($cancel_url);
		}
	}


	function get_error () {
		
		$this->_checkCancelOrder();
		
		//even no error occured or the code doesnt belong to this paymentMethod
		if (!isset($_GET['payment_error']) || $_GET['payment_error'] != $this->code) {
			return false;
		}

		//we found an error...

		$this->enabled = false;

		$errormsgArray = array();
		$title = MODULE_PAYMENT_SOFORT_MULTIPAY_TEXT_ERROR_HEADING;
		if(isset($_GET['error_codes'])) {

			$langConstantExist = true;
			$errorCodes = array_unique (explode(',', helperFunctions::htmlMask($_GET['error_codes'])));
			foreach ($errorCodes as $errorCode) {
				$errorCode = trim($errorCode); //something like "8020" or "8010.invoice_adress.firstname"
				$code = strstr($errorCode, '.', true); //something like "8020" or "8010"
				if($code === false) {
					$code = $errorCode;
				}

				//First watch for something like "...XML_FAULT_8010.INVOICE_ADRESS.FIRSTNAME"
				if (defined ('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_' . strtoupper($errorCode) ) ) {
					$errormsgArray[] = constant ('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_' . strtoupper($errorCode) ) . ' (' . $code . ')';
				//if not found watch for something like "...XML_FAULT_8010"
				}else if (defined('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_' . $code) ) {
					$errormsgArray[] = constant ('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_' . strtoupper($code) ) . ' (' . $code . ')';
				//if not found, we will notice this here
				} else {
					//specific errorinfo not defined - should never appear
					$langConstantExist = false;
				}

				//dont hide this paymentMethod at paymentpage with this codes
				$dontDisableCodes = array('10000', '10001', '10002');
				if(in_array($code, $dontDisableCodes) ) {
					$this->enabled = true;
				}
			}
			//we only found unknown errorCodes => show global error message
			if (!$errormsgArray && $langConstantExist == false) {
				$errormsgArray[] = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_'.$this->paymentMethod);
			}
		}else{
			//error belong to this paymentMethod but we dont have more info about the error
			$errormsgArray[] = constant('MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_TEXT_ERROR_MESSAGE');
		}

		//should never appear
		if (!$errormsgArray) {
			$errormsgArray[] = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_'.$this->paymentMethod);
		}

		$errormsgArray = array_unique($errormsgArray);

		return array('title' => $title,
			'error' => implode(' ', $errormsgArray) );
	}


	/**
	 * Module is active and set "enabled"?
	 */
	function check() {
		if (!isset($this->_check)) {
			$constantName = 'MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_STATUS';
			$check_query = xtc_db_query("SELECT configuration_value FROM " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " WHERE configuration_key = '".HelperFunctions::escapeSql($constantName)."'");
			$this->_check = xtc_db_num_rows($check_query);
		}
		if($this->_check) {
			if(!defined('MODULE_PAYMENT_SOFORT_MULTIPAY_CANCELED_ORDER_STATUS_ID')) {
				$sofortStatuses = $this->insertAndReturnSofortStatus();
				$abortedStatus = (isset($sofortStatuses['aborted']) && !empty($sofortStatuses['aborted'])) ? $sofortStatuses['aborted'] :  '';
				xtc_db_query("INSERT INTO " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, use_function, date_added) values ('MODULE_PAYMENT_SOFORT_MULTIPAY_CANCELED_ORDER_STATUS_ID', '".HelperFunctions::escapeSql($abortedStatus)."',  '6', '10', 'xtc_cfg_pull_down_order_statuses(', 'xtc_get_order_status_name', now())");
				define('MODULE_PAYMENT_SOFORT_MULTIPAY_CANCELED_ORDER_STATUS_ID', $abortedStatus);
			}
		}
		return $this->_check;
	}


	/**
	 * install shared keys, that are used by all/most multipay-modules
	 * called by module with parent::install();
	 */
	function install() {
		if(!defined('MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY')) {
			xtc_db_query("INSERT INTO " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, date_added) values ('MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY', '',  '6', '4', now())");
			xtc_db_query("INSERT INTO " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, date_added) values ('MODULE_PAYMENT_SOFORT_MULTIPAY_AUTH', '---',  '6', '4', 'xtc_cfg_select_option(array(),', now())");  //hide the input-field with an empty <select>
			xtc_db_query("INSERT INTO " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, date_added) values ('MODULE_PAYMENT_SOFORT_MULTIPAY_REASON_1', 'Nr. {{order_id}} Kd-Nr. {{customer_id}}',  '6', '4', 'xtc_cfg_select_option(array(\'Nr. {{order_id}} Kd-Nr. {{customer_id}}\',\'-TRANSACTION-\'), ', now())");
			xtc_db_query("INSERT INTO " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, date_added) values ('MODULE_PAYMENT_SOFORT_MULTIPAY_TEXT_REASON_2', '" . HelperFunctions::escapeSql(STORE_NAME) . "', '6', '4', now())");
			xtc_db_query("INSERT INTO " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, date_added) values ('MODULE_PAYMENT_SOFORT_MULTIPAY_IMAGE', 'Infographic',  '6', '6', 'xtc_cfg_select_option(array(\'Infographic\',\'Logo & Text\'), ', now())");
		}
		return true;
	}


	/**
	 * if this is the last removing of a multipay-paymentmethod --> we also remove all shared keys, that are used by all/most multipay-modules
	 * called by module with parent::remove()
	 */
	function remove() {
		$check_query = xtc_db_query("SELECT * FROM " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " WHERE configuration_key like 'MODULE_PAYMENT_SOFORT_%_STATUS'");
		if (xtc_db_num_rows ($check_query) === 0 ) {
			xtc_db_query("delete from " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " where configuration_key LIKE 'MODULE_PAYMENT_SOFORT_%'");
		}
		return true;
	}


	function _getGenderFromAddressBook($firstname, $lastname, $company, $streetAddress, $postcode, $city, $countryId, $zoneId) {
		$query = 'SELECT entry_gender FROM ' . HelperFunctions::escapeSql(TABLE_ADDRESS_BOOK) . ' WHERE entry_firstname = "' . HelperFunctions::escapeSql($firstname) . '"
		AND entry_lastname = "' . HelperFunctions::escapeSql($lastname) .'"
		AND entry_company = "' . HelperFunctions::escapeSql($company) .'"
		AND entry_street_address = "' . HelperFunctions::escapeSql($streetAddress) .'"
		AND entry_postcode = "' . HelperFunctions::escapeSql($postcode) .'"
		AND entry_city = "' . HelperFunctions::escapeSql($city) .'"
		AND entry_country_id = "' . HelperFunctions::escapeSql($countryId) .'"
		AND entry_zone_id = "' . HelperFunctions::escapeSql($zoneId) .'" LIMIT 1';

		$result = xtc_db_fetch_array(xtc_db_query($query));

		switch ($result['entry_gender']) {
			case 'm': $salutation = 2;
				break;
			case 'f': $salutation = 3;
				break;
			default:  $salutation = '';
				break;
		}
		return $salutation;
	}


	function _checkCancelOrder(){
		global $order;

		/* If temporary order is still in session, check if order ID exists and delete order and all relating (session) data
		 * User might have returned to the shop for changing the order or payment method
		 */
		if (! empty($_SESSION['cart_pn_sofortueberweisung_ID'])) {
			$order_id = substr($_SESSION['cart_pn_sofortueberweisung_ID'], strpos($_SESSION['cart_pn_sofortueberweisung_ID'], '-') + 1);
			$cartID = substr($_SESSION['cart_pn_sofortueberweisung_ID'], 0, strlen($_SESSION['cart']->cartID));
			$check_query = xtc_db_query("SELECT currency, orders_status FROM " . HelperFunctions::escapeSql(TABLE_ORDERS) . " WHERE orders_id = '" . (int) $order_id . "'");
			$result = xtc_db_fetch_array($check_query);
			$constantValue = constant ('MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_TMP_STATUS_ID');
			if (($result['orders_status'] == $constantValue) || ($result['currency'] != $order->info['currency']) || ($_SESSION['cart']->cartID != $cartID)) {
				$this->_cancel_order( (int) $order_id, 'on');
				unset($_SESSION['cart_pn_sofortueberweisung_ID']);
				unset($_SESSION['tmp_oID']);
			}
		}
	}


	// @see xtc_remove_order() in admin/includes/functions/general.php
	// mods by Gambio
	function _cancel_order($order_id, $restock = false) {
		if ($restock == 'on') {
			// BOF GM_MOD:
			$order_query = xtc_db_query("select orders_products_id, products_id, products_quantity from ".HelperFunctions::escapeSql(TABLE_ORDERS_PRODUCTS)." where orders_id = '".HelperFunctions::escapeSql($order_id)."'");
			while ($order = xtc_db_fetch_array($order_query)) {
				xtc_db_query("update ".HelperFunctions::escapeSql(TABLE_PRODUCTS)." set products_quantity = products_quantity + ".HelperFunctions::escapeSql($order['products_quantity']).", products_ordered = products_ordered - ".HelperFunctions::escapeSql($order['products_quantity'])." where products_id = '".HelperFunctions::escapeSql($order['products_id'])."'");
				// BOF GM_MOD
				if(ATTRIBUTE_STOCK_CHECK == 'true'){
					$gm_get_orders_attributes = xtc_db_query("	SELECT	products_options,
																		products_options_values
																FROM	orders_products_attributes
																WHERE	orders_id = '" . HelperFunctions::escapeSql($order_id) . "'
																AND		orders_products_id = '" . HelperFunctions::escapeSql($order['orders_products_id']) . "'");
					while($gm_orders_attributes = xtc_db_fetch_array($gm_get_orders_attributes)) {
						$gm_get_attributes_id = xtc_db_query("	SELECT	pa.products_attributes_id
																FROM	products_options_values pov,
																		products_options po,
																		products_attributes pa
																WHERE	po.products_options_name = '" . HelperFunctions::escapeSql($gm_orders_attributes['products_options']) . "'
																AND		po.products_options_id = pa.options_id
																AND		pov.products_options_values_id = pa.options_values_id
																AND		pov.products_options_values_name = '" . HelperFunctions::escapeSql($gm_orders_attributes['products_options_values']) . "'
																AND		pa.products_id = '" . HelperFunctions::escapeSql($order['products_id']) . "'
																LIMIT	1");
						if(xtc_db_num_rows($gm_get_attributes_id) == 1){
							$gm_attributes_id = xtc_db_fetch_array($gm_get_attributes_id);
							xtc_db_query("UPDATE products_attributes
														SET attributes_stock = attributes_stock + ".HelperFunctions::escapeSql($order['products_quantity'])."
														WHERE products_attributes_id = '" . HelperFunctions::escapeSql($gm_attributes_id['products_attributes_id']) . "'");
						}
					}
				}
				// EOF GM_MOD
			}
		}

		//update status and customer-history
		$time = strftime(' %Y-%m-%d %H:%M:%S');
		xtc_db_query('UPDATE orders SET orders_status = "'.HelperFunctions::escapeSql(MODULE_PAYMENT_SOFORT_MULTIPAY_CANCELED_ORDER_STATUS_ID).'", last_modified = now() WHERE orders_id = '.HelperFunctions::escapeSql($order_id));
		$sql_data_array = array('orders_id' => (int) $order_id,
								'orders_status_id' => MODULE_PAYMENT_SOFORT_MULTIPAY_CANCELED_ORDER_STATUS_ID ,
								'date_added' => 'sqlcommand:now()',
								'customer_notified' => HelperFunctions::getIniValue('sofortCustomerNotified'),
								'comments' => MODULE_PAYMENT_SOFORT_MULTIPAY_ORDER_CANCELED." ".$time);
		xtc_db_query(HelperFunctions::getEscapedInsertInto(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array));
	}


	/**
	 * Bug: orderstatus must not be 0
	 * check if given orderstatus is 0 --- if yes: DEFAULT_ORDERS_STATUS_ID will be returned ELSE given orderstatus will be returned
	 * @param int $orderstatus
	 */
	function checkStatusId ($orderstatus) {
		if($orderstatus > 0)
			return $orderstatus;
		else
			return DEFAULT_ORDERS_STATUS_ID;
	}


	/**
	 * Check, if needed sofort-lang-constants exists.
	 * If not, include the english-lang-file(s).
	 * @return always true
	 */
	function checkExistingSofortConstants($paymentMethod) {

		$paymentMethod = strtoupper($paymentMethod);

		$allowedPaymentMethods = array('SU', 'SL', 'LS', 'SR', 'SV');
		if(!in_array($paymentMethod, $allowedPaymentMethods)) {
			return true;
		}

		//security check - constant exists if lang-file exists
		if(defined('MODULE_PAYMENT_SOFORT_'.$paymentMethod.'_TEXT_TITLE')) {
			return true;
		}

		$installedModulLangs = array('dutch', 'german', 'english', 'polish'); //currently installed in this module
		if(!in_array($_SESSION['language'], $installedModulLangs)) {
			switch ($paymentMethod) {
				case 'SU':
					include_once('lang/english/modules/payment/sofort_sofortueberweisung.php');
					break;
				case 'SV':
					include_once('lang/english/modules/payment/sofort_sofortvorkasse.php');
					break;
				case 'SL':
					include_once('lang/english/modules/payment/sofort_sofortlastschrift.php');
					break;
				case 'LS':
					include_once('lang/english/modules/payment/sofort_lastschrift.php');
					break;
				case 'SR':
					include_once('lang/english/modules/payment/sofort_sofortrechnung.php');
					break;
				default:
			}
		}
		return true;
	}


	function insertAndReturnSofortStatus($includeSrCanceledStatus = false) {
		require_once dirname(__FILE__).'/sofort_install.php';
		//pnag-langs in this module
		$pnagLangs = array('GERMAN', 'ENGLISH', 'POLISH', 'DUTCH');

		//current installed langs
		$installedLangs = array();
		$orderQuery = xtc_db_query("select languages_id, directory from " . HelperFunctions::escapeSql(TABLE_LANGUAGES));
		while ($result = xtc_db_fetch_array($orderQuery)) {
			$installedLangs[$result['languages_id']] = strtoupper($result['directory']);
		}

		//get the current highest orders_status_id and the next three (four) are for our three (four) status
		$orderQuery = xtc_db_query("SELECT MAX(orders_status_id) AS max_orders_status_id FROM orders_status");
		$maxOrdersStatusIdTemp = xtc_db_fetch_array($orderQuery);
		$orders_status_id_temp = $maxOrdersStatusIdTemp['max_orders_status_id'] + 1;
		$orders_status_id_confirmed = $orders_status_id_temp + 1;
		$orders_status_id_aborted = $orders_status_id_confirmed + 1;
		$orders_status_id_canceled = $orders_status_id_aborted + 1;

		$sofortStatuses = array();
		foreach($pnagLangs as $pnagLang) {

			//we cannot insert the status-strings because we dont know the lang-id
			if(!in_array($pnagLang, $installedLangs)) {
				continue;
			}

			$langId = array_search($pnagLang, $installedLangs);

			//insert temp-Status if not exists
			$newOrdersStatusName = $this->_getNewOrdersStatusName('temp', $pnagLang);
			$sofortStatuses['temp'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName);
			if($sofortStatuses['temp'] === false || $sofortStatuses['temp'] == '') {
				$sofortStatuses['temp'] = $this->_insertStatusInDb($newOrdersStatusName, $orders_status_id_temp, $langId);
			}

			//insert confirmed-Status if not exists
			$newOrdersStatusName = $this->_getNewOrdersStatusName('confirmed', $pnagLang);
			$sofortStatuses['confirmed'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName);
			if($sofortStatuses['confirmed'] === false || $sofortStatuses['confirmed'] == '') {
				$sofortStatuses['confirmed'] = $this->_insertStatusInDb($newOrdersStatusName, $orders_status_id_confirmed, $langId);
			}

			//insert aborted-Status if not exists
			$newOrdersStatusName = $this->_getNewOrdersStatusName('aborted', $pnagLang);
			$sofortStatuses['aborted'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName);
			if($sofortStatuses['aborted'] === false || $sofortStatuses['aborted'] == '') {
				$sofortStatuses['aborted'] = $this->_insertStatusInDb($newOrdersStatusName, $orders_status_id_aborted, $langId);
			}

			//insert canceled-Status if not exists (only SR)
			if($includeSrCanceledStatus) {
				$newOrdersStatusName = $this->_getNewOrdersStatusName('canceled', $pnagLang);
				$sofortStatuses['canceled'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName);
				if($sofortStatuses['canceled'] === false || $sofortStatuses['canceled'] == '') {
					$sofortStatuses['canceled'] = $this->_insertStatusInDb($newOrdersStatusName, $orders_status_id_canceled, $langId);
				}
			}
		}
		return  $sofortStatuses;
	}


	function _getStatusIdIfExistInDb($newOrdersStatusName) {
		if(!$newOrdersStatusName) return false;
		$checkQuery = xtc_db_query('select orders_status_id from orders_status where orders_status_name = "' . HelperFunctions::escapeSql($newOrdersStatusName) . '" limit 1');
		if (xtc_db_num_rows($checkQuery) < 1) {
			return false;
		}else{
			//if string exists, we save the orders_status_id
			$neededOrdersStatusId = xtc_db_fetch_array($checkQuery);
			return $neededOrdersStatusId['orders_status_id'];
		}
	}


	function _insertStatusInDb($newOrdersStatusName, $orders_status_id, $langId) {
		xtc_db_query("INSERT INTO orders_status (orders_status_id, language_id, orders_status_name)
			values ('".HelperFunctions::escapeSql($orders_status_id)."', '".HelperFunctions::escapeSql($langId)."', '".HelperFunctions::escapeSql($newOrdersStatusName)."')");
		return $orders_status_id;
	}


	/**
	 * returns the statusname for the given $status and $lang
	 * return max the first 32 chars! (because db-field = varchar(32) )
	 */
	function _getNewOrdersStatusName($status, $lang) {
		switch ($status) {
			case 'temp':
				$newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_TEMP_'.$lang);
				break;
			case 'confirmed':
				$newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_CONFIRMED_'.$lang);
				break;
			case 'aborted':
				$newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_ABORTED_'.$lang);
				break;
			case 'canceled':
				$newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_CANCELED_'.$lang);
				break;
		}
		//we must cut the string because db-field is varchar(32) - otherwise we insert this status with every modul-installaion again
		$newOrdersStatusName = substr($newOrdersStatusName, 0, 32);

		return $newOrdersStatusName;
	}
}
